/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package Parser;

import java.util.Stack;

/**
 * Esta clase encapsula la pila para asegurar que se cumpla con la estructura jerarquica del XML y que
 * cada etiqueta se cierre como corresponde.
 * @author Administrador
 */
public class PilaEqulibrio {
    
    private Stack<String> pila;//Pila que almacena los nombres de cada una de las etiquetas
    private boolean esUsado; //Si se usa o no la pila en algún momento del parseo
    private int raiz; //Numero de elementos raiz

    /**
     * Constructor sin parametros que crea una pila y le da valor al booleano
     */
    public PilaEqulibrio() {
        pila = new Stack<String>();
        esUsado = false;
    }

    /**
     * Borra todos las etiquetas de la pila
     */
    public void clear() {
        this.pila.clear();
        esUsado = false;
    }

    /**
     * Determina si el XML es valido o no.
     * Verifica si la pila de etiquetas está vacía, si el XML tiene un único elemento raíz
     * @return true si es valido, false si no
     */
    public boolean esValido() {
        return pila.empty() && esUsado && raiz == 1;
    }

    /**
     * En caso de ser una etiqueta de apertura, la agrega en la pila. Si es de cierre, verifica que se corresponda
     * con el nombre de la etiqueta de la cima, en caso afirmativo, extrae dicha etiqueta. Si es una etiqueta autocontenida
     * no hace nada.
     * @param leida nombre de la etiqueta leida
     * @param clasificacionTag tipo de etiqueta
     */
    public void agregar( String leida, int clasificacionTag) {
        String tag = leida.toLowerCase();

        if (!esUsado) {
            esUsado = true;
        }

        switch (clasificacionTag) {
            //Si esw de apertura, se guarda en la pila
            case ClasificadorEtiqueta.TAG_INICIO:
                pila.push(tag);
                break;
            //Si es autocontenido, no se guarda ya que no es necesario
            case ClasificadorEtiqueta.TAG_AUTOCONTENIDO:
                break;
            //Si es de cierre 
            case ClasificadorEtiqueta.TAG_FINAL:
                if (comprobarConCima(tag)) {
                    pila.pop();
                    if (pila.isEmpty()) {
                        raiz++; //es el elemnto
                    }
                }
                break;
        }
    }

    /**
     * Comprueba si el nombre de la etiqueta recibido por parametro es igual al nombre
     * de la etiqueta de la cima.
     * @param nombreEtiqueta nombre de la etiqueta a verificar con la cima
     * @return 
     */
    private boolean comprobarConCima(String nombreEtiqueta) {
        String ultimo =pila.peek(); //leemos la cima sin borrar
        return ultimo.equals(nombreEtiqueta);
    }

    /**
     * Determina el porblema por el que el XML no es valido
     * @return cadena de error
     */
    public String identificarCausaError() {
         String causa = "";

        if (!pila.isEmpty()) {
            causa = "El XML no está balanceado\n";
        }

        if (!this.esUsado) {
            causa += "El XML no tiene elementos\n";
        }

        if (raiz != 1) {
            causa += "Número incorrecto de los elementos raiz";
        }
        return causa;
    }
    

}
